<?php
/**
 * Description: 获取首页数据
 * User: devforma
 * Date: 15/4/7
 * Time: 20:04
 */
require __DIR__ . '/includes/utils.php';
require LIB_DIR . '/LiveCourse.class.php';

class GetEntryData implements iController {
    private $userId, $platform;

    /**
     * api请求处理主函数
     * @param array $queryArgs 就是$_REQUEST变量
     * @return array api返回结果，必须含response_code
     */
    public function output($queryArgs) {
        global $cmsdb;
        
        if (validateUser($queryArgs) !== 1)
            return genOutput(1000);

        $this->userId = $queryArgs['user_id'];
        $this->platform = $queryArgs['terminal_type'];

        $userData = getUserData($this->userId);
        if (empty($userData))
            return genOutput(1000);

        /**--------------------------------------------------------------
         * 获取预估分排名信息
         */
        $rank = getEvaluateRank($userData->exam_detail_id, $userData->score);
        $assessment = array(
            'score' => intval($userData->score),
            'rank' => round($rank, 2)
        );


        /**--------------------------------------------------------------
         * 获取今天的mini模考信息
         */
        if ($miniMock = getMiniMockInfo(date('Y-m-d'))) {

            //查询用户对mini模考的做题状态
            $miniMockUsers = getMiniMockUsers($miniMock['id']);
            $exists = isset($miniMockUsers[$this->userId]) ? $miniMockUsers[$this->userId] : false;

            //设置答题状态
            $defeat = 0.0;
            if ($exists && $exists['status'] == 1) { //已完成
                $status = 'done';
                $paperId = $exists['id'];

                //计算击败了多少
                $rank = $miniMock['rank'];

                $total = $lower = 0;
                $userScore = intval($exists['evaluate']);
                foreach ($rank as $score => $persons) {
                    $total += $persons;
                    if ($score < $userScore) {
                        $lower += $persons;
                    }
                }
                $defeat = round($lower/$total, 2);

            } elseif ($exists && $exists['status'] == 2) { //未完成
                $status = 'undone';
                $paperId = $exists['id'];

            } else { //还没做
                $status = 'fresh';
                $paperId = $miniMock['id'];
            }

            $today = array(
                'id' => intval($paperId),
                'persons_num' => intval($miniMock['persons_num']),
                'status' => $status,
                'defeat' => $defeat,
                'name' => $miniMock['name'],
                'description' => $miniMock['description']
            );

        } else {
            $today = array(
                'id' => 0,
                'persons_num' => 0,
                'status' => 'fresh',
                'defeat' => 0.0,
                'name' => '',
                'description' => ''
            );
        }
        
        
        /**--------------------------------------------------------------
         * 获取推荐知识点
         */
        $recomendNoteId = $this->getCurrentRecomendNote(normalizeUserNoteInfo($userData->note_info));
        $noteInfo = array(
            'id' => $recomendNoteId,
            'name' => $this->getNoteName($recomendNoteId),
            'description' => getPaperType('专项练习')->remark
        );

        
        return genOutput(1, array(
            'assessment' => $assessment,
            'paper' => array(
                'today' => $today,
                'note' => $noteInfo
            ),
            'live_course' => $this->getOpenCourse(),
            'latest_notify' => $this->getLatestNotify(),
            'exam_info' => $this->getExamInfo($userData->exam_detail_id)
        ));

    }

    /**
     * 获取当前的推荐知识点
     *
     * @param array $notes note_info知识点数组
     * @return int
     */
    private function getCurrentRecomendNote(&$notes) {
        global $cmsdb;
        $hierarchy = getNewNoteHierarchy();

        $shouldChooseNew = false; //用于标记已经存在的推荐知识点不可用，需要重新选择一个
        foreach ($notes as $noteId => &$note) {
            $note = array_values($note);

            if (isset($note[4]) && $note[4] == 1) { //获取当前的推荐知识点

                if (isset($hierarchy[$noteId]) && $hierarchy[$noteId]['note_type'] == 1) { //该推荐知识点可用
                    return intval($noteId);
                } else { //不可用，需重新选择
                    $note[4] = 0;
                    $shouldChooseNew = true;
                }

            } elseif ($shouldChooseNew && isset($hierarchy[$noteId])) { //需要重新选择推荐知识点且知识点可用
                $note[4] = 1;

                //更新知识点信息并清除缓存
                $cmsdb->update('qb_user_data', array('note_info' => json_encode($notes)), array('user_id' => $this->userId));
                cacheDelete('qb_userData:'.$this->userId);

                return intval($noteId);
            }
        }

        //如果没有推荐知识点,取第一个知识点作为推荐知识点
        reset($notes);
        return key($notes);
    }

    /**
     * 获取知识点名称
     *
     * @param int $noteId 知识点id
     * @return string
     */
    private function getNoteName($noteId) {
        $notes = getNewNoteHierarchy();
        
        if (isset($notes[$noteId]))
            return strval($notes[$noteId]['name']);
        
        return '';
    }

    /**
     * 获取考试信息
     *
     * @param $examId
     * @return mixed
     */
    private function getExamInfo($examId) {
        global $cmsdb;

        $cacheKey = 'qb:func:getExamInfo:'.$examId;
        if (($value = cacheGet($cacheKey)) == null) {
            $sql = "SELECT e.exam_name, ed.id, e.shortening, ed.is_official, ed.exam_day FROM `data_exams` AS e
            INNER JOIN `data_exam_detail` AS ed ON e.exam_id=ed.exam_id AND ed.id=:id";
            $exam = $cmsdb->getRow($sql, array(':id' => $examId));

            $value = array(
                'name' => $exam->exam_name,
                'code' => $exam->shortening,
                'exam_id' => intval($exam->id),
                'is_official' => $exam->is_official ? true : false,
                'is_interview' => false,
                'date' => $exam->exam_day
            );

            cacheAdd($cacheKey, $value, 20*60);
        }

        return $value;
    }

    /**
     * 获取最新的通知id，用于app端小红点的展示
     */
    private function getLatestNotify() {
        global $cmsdb;

        $cacheKey = 'func:getLatestNotify:quizbank';
        if (($value = cacheGet($cacheKey)) == null) {
            $sql = 'SELECT `id` FROM `qb_notify` WHERE `app_type`="quizbank" ORDER BY `id` DESC LIMIT 1';
            $value = $cmsdb->getVar($sql);
            
            cacheAdd($cacheKey, $value, 10*60);
        }

        return intval($value);
    }

    /**
     * 获取最近公开新课信息
     */
    private function getOpenCourse() {
        $openCourse = array(
            'type' => 0, //0代表跳转到固定的课程页
            'content' => '',
            'course_name' => ''
        );

        //获取最近的公开课
        $course = LiveCourse::getLatestOpenCourse();

        if (empty($course)) { //没有可用的公开课，去查看往期
            $nickname = $this->getUserNickname($this->userId);
            $openCourse['content'] = LiveCourse::getStaticCourseUrl($this->userId, $nickname, $this->platform);

            return $openCourse;
        }
        
        if (strtotime($course->class_starttime) - 10*60 > time()) { //还没开始上课
            $openCourse['type'] = 2;
        } else { //正在上课
            $openCourse['type'] = 1;
        }
        $openCourse['content'] = strval($course->id);
        $openCourse['course_name'] = $course->course_name;

        return $openCourse;
    }

    /**
     * 获取用户昵称
     * @param int $userId 用户id
     * @return string
     */
    private function getUserNickname($userId) {
        global $uddb;
        $nickname = $uddb->getVar('SELECT `nickname` FROM `user_social_info` WHERE `user_id`='.$userId);
        if (empty($nickname))
            $nickname = 'student_'. $userId;

        return $nickname;
    }

}